feat: 프로젝트 basic CRUD 구성 - #16
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthrough프로젝트 생성·목록·상세·수정·삭제 API가 추가되었습니다. 프로젝트 엔티티와 멤버 권한 모델, 요청·응답 DTO, JPA 저장소, 서비스 검증 및 커서 기반 목록 조회가 구현되었습니다. Changes프로젝트 관리 API
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant ProjectController
participant ProjectService
participant ProjectRepository
participant ProjectMemberRepository
Client->>ProjectController: 프로젝트 API 요청 및 X-USER-ID 헤더 전달
ProjectController->>ProjectService: 프로젝트 작업 호출
ProjectService->>ProjectRepository: 프로젝트 조회·저장·삭제
ProjectService->>ProjectMemberRepository: 멤버 권한 및 목록 조회
ProjectService-->>ProjectController: 프로젝트 응답 반환
ProjectController-->>Client: ApiResponse 반환
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/slatto/domain/project/entity/Project.java`:
- Around line 70-137: Update Project’s constructor and updateInfo to validate
that endDate is not earlier than startDate before assigning or persisting it.
For creation, compare against the initialized current start date; for updates,
compare against the project’s existing startDate, and reject invalid dates using
the entity’s established validation approach.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: a8e48c0a-9a23-4481-b01a-733b4effc4a5
📒 Files selected for processing (16)
src/main/java/com/slatto/domain/project/controller/ProjectController.javasrc/main/java/com/slatto/domain/project/converter/ProjectConverter.javasrc/main/java/com/slatto/domain/project/dto/ProjectCreateRequest.javasrc/main/java/com/slatto/domain/project/dto/ProjectDetailResponse.javasrc/main/java/com/slatto/domain/project/dto/ProjectListResponse.javasrc/main/java/com/slatto/domain/project/dto/ProjectResponse.javasrc/main/java/com/slatto/domain/project/dto/ProjectUpdateRequest.javasrc/main/java/com/slatto/domain/project/entity/Project.javasrc/main/java/com/slatto/domain/project/entity/ProjectMember.javasrc/main/java/com/slatto/domain/project/entity/ProjectUserRole.javasrc/main/java/com/slatto/domain/project/exception/ProjectErrorCode.javasrc/main/java/com/slatto/domain/project/repository/ProjectMemberRepository.javasrc/main/java/com/slatto/domain/project/repository/ProjectRepository.javasrc/main/java/com/slatto/domain/project/repository/ProjectUserRoleRepository.javasrc/main/java/com/slatto/domain/project/service/ProjectService.javasrc/main/java/com/slatto/domain/user/repository/UserRepository.java
|
|
||
| private Project( | ||
| Users ownerUser, | ||
| String title, | ||
| CategoryName type, | ||
| String customTypeName, | ||
| LengthType lengthType, | ||
| String description, | ||
| LocalDate endDate, | ||
| String clientName, | ||
| Kind kind | ||
| ) { | ||
| this.ownerUser = ownerUser; | ||
| this.title = title; | ||
| this.type = type; | ||
| this.customTypeName = customTypeName; | ||
| this.lengthType = lengthType; | ||
| this.description = description; | ||
| this.startDate = LocalDate.now(); | ||
| this.endDate = endDate; | ||
| this.clientName = clientName; | ||
| this.status = DEFAULT_STATUS; | ||
| this.kind = kind; | ||
| } | ||
|
|
||
| public static Project create( | ||
| Users ownerUser, | ||
| String title, | ||
| CategoryName type, | ||
| String customTypeName, | ||
| LengthType lengthType, | ||
| String description, | ||
| LocalDate endDate, | ||
| String clientName, | ||
| Kind kind | ||
| ) { | ||
| return new Project( | ||
| ownerUser, | ||
| title, | ||
| type, | ||
| customTypeName, | ||
| lengthType, | ||
| description, | ||
| endDate, | ||
| clientName, | ||
| kind | ||
| ); | ||
| } | ||
|
|
||
| public void updateInfo( | ||
| String title, | ||
| CategoryName type, | ||
| String customTypeName, | ||
| LengthType lengthType, | ||
| String description, | ||
| LocalDate endDate, | ||
| String clientName, | ||
| Kind kind | ||
| ) { | ||
| this.title = title; | ||
| this.type = type; | ||
| this.customTypeName = customTypeName; | ||
| this.lengthType = lengthType; | ||
| this.description = description; | ||
| this.endDate = endDate; | ||
| this.clientName = clientName; | ||
| this.kind = kind; | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
endDate가 시작일 이전이어도 생성/수정이 허용됩니다.
create/updateInfo 어디에서도 endDate가 startDate(생성 시점의 오늘 날짜) 이후인지 검증하지 않습니다. 잘못된 기간의 프로젝트가 그대로 저장될 수 있으며, ProjectConverter#calculateDeadlineProgressPercent가 이 경우 무조건 100%를 반환하는 것도 이 누락의 증상입니다(관련 코멘트는 통합 코멘트 섹션 참고).
제안: 생성자/updateInfo에 유효성 검증 추가
private Project(
Users ownerUser,
String title,
CategoryName type,
String customTypeName,
LengthType lengthType,
String description,
LocalDate endDate,
String clientName,
Kind kind
) {
+ LocalDate startDate = LocalDate.now();
+ if (!endDate.isAfter(startDate)) {
+ throw new ProjectException(ProjectErrorCode.INVALID_PROJECT_PERIOD);
+ }
this.ownerUser = ownerUser;
this.title = title;
this.type = type;
this.customTypeName = customTypeName;
this.lengthType = lengthType;
this.description = description;
- this.startDate = LocalDate.now();
+ this.startDate = startDate;
this.endDate = endDate;
this.clientName = clientName;
this.status = DEFAULT_STATUS;
this.kind = kind;
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/slatto/domain/project/entity/Project.java` around lines 70
- 137, Update Project’s constructor and updateInfo to validate that endDate is
not earlier than startDate before assigning or persisting it. For creation,
compare against the initialized current start date; for updates, compare against
the project’s existing startDate, and reject invalid dates using the entity’s
established validation approach.
🔗 관련 이슈 (Related Issue)
📝 작업 내용
이번 PR에서는 프로젝트 생성, 목록 조회, 상세 조회, 수정, 삭제를 처리하기 위한 기본 CRUD 구조를 추가했습니다.
프로젝트 도메인 메서드, 요청/응답 DTO, Converter, Repository, Service, Controller를 연결하여 프로젝트 파트 개발을 시작할 수 있는 기본 흐름을 구성했습니다.
주요 검토 파일
프로젝트 API
src/main/java/com/slatto/domain/project/controller/ProjectController.java- 프로젝트 기본 CRUD 엔드포인트 추가src/main/java/com/slatto/domain/project/service/ProjectService.java- 프로젝트 생성/목록/상세/수정/삭제 비즈니스 로직 추가프로젝트 DTO / Converter
src/main/java/com/slatto/domain/project/dto/ProjectCreateRequest.java- 프로젝트 생성 요청 DTO 추가src/main/java/com/slatto/domain/project/dto/ProjectUpdateRequest.java- 프로젝트 수정 요청 DTO 추가src/main/java/com/slatto/domain/project/dto/ProjectResponse.java- 프로젝트 기본 응답 DTO 추가src/main/java/com/slatto/domain/project/dto/ProjectListResponse.java- 프로젝트 목록 응답 DTO 추가src/main/java/com/slatto/domain/project/dto/ProjectDetailResponse.java- 프로젝트 상세 응답 DTO 추가src/main/java/com/slatto/domain/project/converter/ProjectConverter.java- Entity/DTO 변환 로직 추가프로젝트 도메인 / Repository
src/main/java/com/slatto/domain/project/entity/Project.java- 프로젝트 생성/수정/상태 변경/삭제 도메인 메서드 추가src/main/java/com/slatto/domain/project/entity/ProjectMember.java- 프로젝트 멤버 생성/권한 확인/탈퇴 도메인 메서드 추가src/main/java/com/slatto/domain/project/entity/ProjectUserRole.java- 프로젝트 내 역할 생성 메서드 추가src/main/java/com/slatto/domain/project/repository/ProjectRepository.java- 프로젝트 조회 및 생성 개수 조회 메서드 추가src/main/java/com/slatto/domain/project/repository/ProjectMemberRepository.java- 프로젝트 멤버 조회, 목록 조회, 멤버 미리보기 조회 메서드 추가src/main/java/com/slatto/domain/project/repository/ProjectUserRoleRepository.java- 프로젝트 역할 조회 메서드 추가src/main/java/com/slatto/domain/user/repository/UserRepository.java- 삭제되지 않은 사용자 조회 메서드 추가프로젝트 예외
src/main/java/com/slatto/domain/project/exception/ProjectErrorCode.java- 프로젝트 도메인 에러 코드 추가1. 프로젝트 생성 기능 추가
로그인한 사용자가 프로젝트를 생성할 수 있도록 기본 생성 흐름을 추가했습니다.
ADMIN으로 설정ProjectUserRole로 저장무료 계정은 최대 5개의 프로젝트만 생성할 수 있도록 처리했습니다.
2. 프로젝트 목록 조회 기능 추가
내가 참여 중인 프로젝트 목록을 조회할 수 있도록 구현했습니다.
지원하는 조회 조건은 다음과 같습니다.
status- 프로젝트 상태 필터cursor- cursor pagination 기준 IDsize- 조회 개수응답은 목록 API 컨벤션에 맞춰
result.items구조로 구성했습니다.{ "isSuccess": true, "code": "COMMON200", "message": "요청에 성공했습니다.", "result": { "items": [], "nextCursor": null, "hasNext": false } }3. 프로젝트 상세 조회 기능 추가
프로젝트 상세 화면에서 필요한 기본 정보를 조회할 수 있도록 구성했습니다.
상세 응답에는 다음 정보가 포함됩니다.
4. 프로젝트 수정 및 삭제 기능 추가
프로젝트 수정과 삭제 기능을 추가했습니다.
수정/삭제는
ADMIN권한을 가진 프로젝트 멤버만 가능하도록 검증했습니다.삭제는 실제 DB row를 제거하지 않고
deletedAt을 기록하는 soft delete 방식으로 처리했습니다.5. 프로젝트 도메인 예외 코드 추가
프로젝트 도메인에서 사용할 에러 코드를 추가했습니다.
PROJECT404- 프로젝트를 찾을 수 없음PROJECT_MEMBER404- 프로젝트 멤버를 찾을 수 없음PROJECT403- 프로젝트 접근 권한 없음PROJECT_ADMIN403- 프로젝트 관리자 권한 필요PROJECT409- 무료 계정 프로젝트 생성 제한 초과6. 임시 인증 헤더 적용
아직 JWT 인증 구조가 연결되지 않았기 때문에, 현재는 임시로
X-USER-ID헤더에서 사용자 ID를 받아 처리하도록 구성했습니다.X-USER-ID: 1추후 인증 모듈이 연결되면
@AuthenticationPrincipal또는 공통 인증 유틸 기반으로 교체할 예정입니다.✅ PR 체크리스트
./gradlew compileJava로 컴파일을 확인했습니다.Summary by CodeRabbit